//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

import React, { useEffect, useState } from 'react';
import type { NodeProps } from "reactflow";
import { GitExtraInfo, NodeData } from '../types';
import LocalNodeWrap from '../LocalNodeWrap';
import type { GitLabCommit } from "@/api/gitlab/commit";
import { list_commit } from "@/api/gitlab/commit";
import { list_branch } from "@/api/gitlab/branch";
import { list_tag } from "@/api/gitlab/tag"
import { Button, Select, Space, Table } from 'antd';
import { ExportOutlined, ReloadOutlined } from '@ant-design/icons';
import type { GitLabRepo } from "@/api/gitlab/repo";
import { get_repo } from "@/api/gitlab/repo";
import { get_type_name, type UserDataSourceInfo, type GitSourceInfo, get_source } from '@/api/user_dataview';
import { open as shell_open } from '@tauri-apps/api/shell';
import type { ColumnsType } from 'antd/lib/table';
import moment from 'moment';


const GitLabCommitListNode = (props: NodeProps<NodeData>) => {

    const [commitList, setCommitList] = useState<GitLabCommit[]>([]);
    const [repoInfo, setRepoInfo] = useState<GitLabRepo | null>(null);
    const [refNameList, setRefNameList] = useState<string[]>([]);
    const [curRefName, setCurRefName] = useState("");
    const [dataSource, setDataSource] = useState<UserDataSourceInfo | undefined>(undefined);

    const loadDataSource = async () => {
        const res = await get_source(props.data.dataSourceId ?? "");
        setDataSource(res);
    };

    const loadRepoInfo = async () => {
        if (dataSource == undefined) {
            return;
        }
        const sourceInfo = JSON.parse(dataSource.source_info) as GitSourceInfo;
        const url = new URL(sourceInfo.baseUrl ?? "");
        const baseUrl = `${url.protocol}//${url.host}`;
        const extraInfo = props.data.extraInfo as GitExtraInfo;
        const res = await get_repo(baseUrl, sourceInfo.accessToken, extraInfo.repoName);
        setRepoInfo(res);
        setCurRefName(res.default_branch);
    };

    const loadRefNameList = async () => {
        if (dataSource == undefined) {
            return;
        }
        const sourceInfo = JSON.parse(dataSource.source_info) as GitSourceInfo;
        const url = new URL(sourceInfo.baseUrl ?? "");
        const baseUrl = `${url.protocol}//${url.host}`;
        const extraInfo = props.data.extraInfo as GitExtraInfo;

        const branchList = await list_branch(baseUrl, sourceInfo.accessToken, extraInfo.repoName);
        const tagList = await list_tag(baseUrl, sourceInfo.accessToken, extraInfo.repoName);
        const tmpList = [
            ...(branchList.map(item => item.name)),
            ...(tagList.map(item => item.name)),
        ];
        setRefNameList(tmpList);
    };

    const loadCommitList = async () => {
        if (dataSource == undefined) {
            return;
        }
        const sourceInfo = JSON.parse(dataSource.source_info) as GitSourceInfo;
        const url = new URL(sourceInfo.baseUrl ?? "");
        const baseUrl = `${url.protocol}//${url.host}`;
        const extraInfo = props.data.extraInfo as GitExtraInfo;
        const res = await list_commit(baseUrl, sourceInfo.accessToken, extraInfo.repoName, curRefName);
        setCommitList(res);
    };

    const getSourceTypeName = () => {
        if (dataSource == undefined) {
            return "";
        }
        return get_type_name(dataSource.source_type);
    };

    const columns: ColumnsType<GitLabCommit> = [
        {
            title: "id",
            width: 100,
            dataIndex: "short_id",
        },
        {
            title: "标题",
            render: (_, row: GitLabCommit) => (
                <a href={row.web_url} target="_blank" rel="noreferrer">{row.title}&nbsp;<ExportOutlined /></a>
            ),
        },
        {
            title: "提交人名称",
            width: 150,
            dataIndex: "committer_name",
        },
        {
            title: "提交人邮件",
            width: 150,
            dataIndex: "committer_email",
        },
        {
            title: "提交时间",
            width: 120,
            render: (_, row: GitLabCommit) => moment(row.committed_date).format("YYYY-MM-DD HH:mm"),
        },
    ];


    useEffect(() => {
        loadDataSource();
    }, []);

    useEffect(() => {
        if (curRefName != "" && dataSource != undefined) {
            loadCommitList();
        }
    }, [curRefName, dataSource]);

    useEffect(() => {
        if (dataSource != undefined) {
            loadRepoInfo();
            loadRefNameList();
        }
    }, [dataSource]);

    return (
        <LocalNodeWrap title={
            <Space>
                <span>{getSourceTypeName()}</span>
                <span>提交列表</span>
                {repoInfo != null && (
                    <a onClick={e => {
                        e.stopPropagation();
                        e.preventDefault();
                        shell_open(repoInfo.web_url);
                    }}>{repoInfo.path_with_namespace}</a>
                )}
            </Space>
        } nodeData={props} extraButtonList={[
            (
                <Select value={curRefName} onChange={value => setCurRefName(value)}
                    style={{ width: "80px" }}>
                    <Select.Option value="">默认分支</Select.Option>
                    {refNameList.map(refName => (
                        <Select.Option key={refName} value={refName}>{refName}</Select.Option>
                    ))}
                </Select>
            ),
            (
                <Button type="text" icon={<ReloadOutlined />} onClick={e => {
                    e.stopPropagation();
                    e.preventDefault();
                    loadCommitList();
                }} title='刷新' />
            ),
        ]} canChangeBgColor={false}>
            <Table rowKey="id" dataSource={commitList} columns={columns} pagination={false} scroll={{ y: props.data.height - 100 }} className="nodrag nopan nowheel"
            />
        </LocalNodeWrap>
    );
};

export default GitLabCommitListNode;